#include "rtsp_request_reponse.h"
#include "rtsp_client.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pthread.h>
#include <sys/utsname.h>
#include <unistd.h>
#include <linux/errno.h>
#include <errno.h>

#define RTSP_EL "\r\n"
#define RTSP_VER "RTSP/1.0"
#define HDR_REQUIRE "Require"
#define HDR_ACCEPT "Accept"
#define PACKAGE "ezrtspd"
#define VERSION "1.0"
#define SDP_EL "\r\n"
#define HDR_TRANSPORT "Transport"
#define HDR_SESSION "Session"


#define RTP_DEFAULT_PORT 5004
static int start_port=RTP_DEFAULT_PORT;

#define DEFAULT_TTL 32

RtspMethod get_rtsp_method(char* buffer)
{
	char method[32];

	sscanf(buffer, "%31s", method);
	
	if (strcmp(method, "OPTIONS") == 0) {
		return RTSP_OPTIONS;
	}
	if (strcmp(method, "DESCRIBE") == 0) {
		return RTSP_DESCRIBE;
	}
	if (strcmp(method, "SETUP") == 0) {
		return RTSP_SETUP;
	}
	if (strcmp(method, "PLAY") == 0) {
		return RTSP_PLAY;
	}
	if (strcmp(method, "TEARDOWN") == 0) {
		return RTSP_TERARDOWN;
	}

	return RTSP_INVALID_METHOD;	
}

char *_get_stat(int err)
{
	struct {
		char *token;
		int code;
	} status[] = {
		{
		"Continue", 100}, {
		"OK", 200}, {
		"Created", 201}, {
		"Accepted", 202}, {
		"Non-Authoritative Information", 203}, {
		"No Content", 204}, {
		"Reset Content", 205}, {
		"Partial Content", 206}, {
		"Multiple Choices", 300}, {
		"Moved Permanently", 301}, {
		"Moved Temporarily", 302}, {
		"Bad Request", 400}, {
		"Unauthorized", 401}, {
		"Payment Required", 402}, {
		"Forbidden", 403}, {
		"Not Found", 404}, {
		"Method Not Allowed", 405}, {
		"Not Acceptable", 406}, {
		"Proxy Authentication Required", 407}, {
		"Request Time-out", 408}, {
		"Conflict", 409}, {
		"Gone", 410}, {
		"Length Required", 411}, {
		"Precondition Failed", 412}, {
		"Request Entity Too Large", 413}, {
		"Request-URI Too Large", 414}, {
		"Unsupported Media Type", 415}, {
		"Bad Extension", 420}, {
		"Invalid Parameter", 450}, {
		"Parameter Not Understood", 451}, {
		"Conference Not Found", 452}, {
		"Not Enough Bandwidth", 453}, {
		"Session Not Found", 454}, {
		"Method Not Valid In This State", 455}, {
		"Header Field Not Valid for Resource", 456}, {
		"Invalid Range", 457}, {
		"Parameter Is Read-Only", 458}, {
		"Unsupported transport", 461}, {
		"Internal Server Error", 500}, {
		"Not Implemented", 501}, {
		"Bad Gateway", 502}, {
		"Service Unavailable", 503}, {
		"Gateway Time-out", 504}, {
		"RTSP Version Not Supported", 505}, {
		"Option not supported", 551}, {
		"Extended Error:", 911}, {
		NULL, -1}
	};
	int i;
	for (i = 0; status[i].code != err && status[i].code != -1; ++i);
	return status[i].token;
}

int send_reply(struct RtspClient* thiz, int errornumber)
{
	 char error_buff[1024] = {0};

	 sprintf(error_buff, "%s %d %s"RTSP_EL"CSeq: %d"RTSP_EL, RTSP_VER, errornumber, _get_stat(errornumber), rtsp_client_get_cseq(thiz));
	 
	 //---patch coerenza con rfc in caso di errore
	 // strcat(b, "\r\n");
	 strcat(error_buff, RTSP_EL);
	 
	 write(rtsp_client_get_fd(thiz), error_buff, strlen(error_buff));
	 
	 return 0;
}

int _get_rtsp_cseg(struct RtspClient* thiz)
{
	char *p;
	char trash[255];
	unsigned int cseq;

	/****check  CSeq****/ 
	if ((p = strstr(rtsp_client_recv_request_string(thiz), "CSeq")) == NULL) {
		/**** not find CSeq send 400 error ****/
		send_reply(thiz, 400);
		return -1;
	} 
	else 
	{
		if(sscanf(p, "%254s %d", trash, &(cseq))!=2){
			/**** not find CSeq value send 400 error ****/	
			send_reply(thiz, 400);
			return -1;
		}
        rtsp_client_set_cseq(thiz, cseq);
	}
	#if 0
	if( strstr(rtsp[cur_conn_num]->in_buffer, "ClientChallenge")){
		return -1;
	}
	#endif
	return 0;
}

int _set_options_reply(struct RtspClient* thiz, int status)
{
    char buffer[2048] = {0};
    int ret = -1;

	sprintf(buffer, "%s %d %s"RTSP_EL"CSeq: %ld"RTSP_EL, RTSP_VER, status, _get_stat(status), (unsigned long)rtsp_client_get_cseq(thiz));
	strcat(buffer, "Public: OPTIONS,DESCRIBE,SETUP,PLAY,PAUSE,TEARDOWN"RTSP_EL);
	strcat(buffer, RTSP_EL);
	
	ret = write(rtsp_client_get_fd(thiz), buffer, strlen(buffer));
	if(ret < 0){
        perror("set options reply failed!\n");
        return -1;
	}

	return 0;
}

int rtsp_options(struct RtspClient* rtsp_client)
{
    if(_get_rtsp_cseg(rtsp_client) == 0){
        _set_options_reply(rtsp_client, 200);
        return 0;        
    }
    
    return -1;
}


int check_rtsp_filename(struct RtspClient* rtsp_client)
{
    return 0;
}

int parse_url(const char *url, char *server, unsigned short *port, char *file_name)
{
	int valid_url = 0;
	char *token,*port_str;
	char temp_url[128]="";
	
	/* copy url */
	strcpy(temp_url, url);
	if (strncmp(temp_url, "rtsp://", 7) == 0) {
		if(strstr(&temp_url[7], ":")){
			/* expects format '[rtsp://server:port/filename' */
			token = strtok(&temp_url[7], " :/\t\n");
			strcpy(server, token);
			port_str = strtok(&temp_url[strlen(server) + 7 + 1], " /\t\n");
			if (port_str)
				*port = (unsigned short) atol(port_str);
			else
				*port = 554;
			valid_url = 1;
			
			printf("token(%s)\n", token);
			token = strtok(NULL, " ");
			if (token)
				strcpy(file_name, token);
			else
				file_name[0] = '\0';
		}
		else{
			/* expects format '[rtsp://server/filename' */
			token = strtok(&temp_url[7], "/");
			strcpy(server, token);
			*port = 554;
			strcpy(file_name, &temp_url[strlen(server) + 7 + 1]);
			valid_url = 1;
		}
	}
	else {
		/* try just to extract a file name */
	}

	return valid_url;
}

int check_rtsp_url(struct RtspClient* rtsp_client)
{
	 unsigned short port;
	 char url[128] = {0};
	 char object[128], server[128];
	 char file_name[128];

	if (!sscanf(rtsp_client_recv_request_string(rtsp_client), " %*s %254s ", url)) {
		send_reply(rtsp_client, 400);	/* bad request */
		return -1;
	}
	/* Validate the URL */
	if (!parse_url(url, server, &port, object)) {
		send_reply(rtsp_client, 400);	/* bad request */
		return -1;
	}

    printf("func(%s), line(%d): server(%s) port(%d)\n", __func__, __LINE__, server, port);
//    printf("Func(%s) Line(%d): object filename(%s) \n", __func__, __LINE__, object);

#if 1
	rtsp_client_set_hostname(rtsp_client, server);

	/****  get media file name   ****/
	if(strstr(object,"trackID")){
		strcpy(object,file_name);
//		strcpy(object,rtsp_client->file_name);
	}
	else{
		if(strcmp(object,"")==0){
            strcpy(object,file_name);
//			strcpy(object,rtsp_client->file_name);
		}

        rtsp_client_set_filename(rtsp_client,object);
//		strcpy(rtsp_client->file_name,object);

		rtsp_client_set_hostname(rtsp_client, object);
	}
#endif 

	return 0;
}


 char *get_SDP_user_name(char *buffer)
 {
	 strcpy(buffer,PACKAGE);
	 return buffer;
 }

 float NTP_time(time_t t)
 {
	 return (float)t+2208988800U;
 }

 char *get_SDP_session_id(char *buffer)
 {	 
	 buffer[0]='\0';
	 sprintf(buffer,"%.0f",NTP_time(time(NULL)));
	 return buffer;  
 }

 char *get_SDP_version(char *buffer)
 {
	 buffer[0]='\0'; 
	 sprintf(buffer,"%.0f",NTP_time(time(NULL)));
	 return buffer;
 }

 char *get_address()
 {
   static char	   Ip[256];
   char server[256];
   u_char		   addr1, addr2, addr3, addr4, temp;
   u_long		   InAddr;
   struct hostent *host;

   gethostname(server,256);
   host = gethostbyname(server);
 
   temp = 0;
   InAddr = *(unsigned int *) host->h_addr;
   addr4 = (unsigned char) ((InAddr & 0xFF000000) >> 0x18);
   addr3 = (unsigned char) ((InAddr & 0x00FF0000) >> 0x10);
   addr2 = (unsigned char) ((InAddr & 0x0000FF00) >> 0x8);
   addr1 = (unsigned char) (InAddr & 0x000000FF);
#if (BYTE_ORDER == BIG_ENDIAN)
   temp = addr1;
   addr1 = addr4;
   addr4 = temp;
   temp = addr2;
   addr2 = addr3;
   addr3 = temp;
#endif
 
   sprintf(Ip, "%d.%d.%d.%d", addr1, addr2, addr3, addr4);
   return Ip;
 }


int get_describe_sdp(char *sdp_buff,struct RtspClient* rtsp_client)
{
	char s[30];
	int payload_type = 96;
	
	if(!sdp_buff)
		return -1;
	strcpy(sdp_buff, "v=0"SDP_EL);	
	strcat(sdp_buff, "o=");
	strcat(sdp_buff,get_SDP_user_name(s));
	strcat(sdp_buff," ");
	strcat(sdp_buff, get_SDP_session_id(s));
	strcat(sdp_buff," ");
	strcat(sdp_buff, get_SDP_version(s));
	strcat(sdp_buff, SDP_EL);
   	strcat(sdp_buff, "c=");
   	strcat(sdp_buff, "IN ");		/* Network type: Internet. */
   	strcat(sdp_buff, "IP4 ");		/* Address type: IP4. */
	//strcat(sdp_buff, get_address());
	strcat(sdp_buff, rtsp_client_get_hostname(rtsp_client));
	strcat(sdp_buff, SDP_EL);
	strcat(sdp_buff, "s=RTSP Session"SDP_EL);
	sprintf(sdp_buff + strlen(sdp_buff), "i=%s %s Streaming Server"SDP_EL, PACKAGE, VERSION);
   	sprintf(sdp_buff + strlen(sdp_buff), "u=%s"SDP_EL, rtsp_client_get_filename(rtsp_client));
   	strcat(sdp_buff, "t=0 0"SDP_EL);	
	/**** media specific ****/
	strcat(sdp_buff,"m=");
	strcat(sdp_buff,"video 0");
	strcat(sdp_buff," RTP/AVP "); /* Use UDP */
	sprintf(sdp_buff + strlen(sdp_buff), "%d"SDP_EL, payload_type);
	if (payload_type>=96) {
		/**** Dynamically defined payload ****/
		strcat(sdp_buff,"a=rtpmap:");
		sprintf(sdp_buff + strlen(sdp_buff), "%d", payload_type);
		strcat(sdp_buff," ");	
		strcat(sdp_buff,"H264/90000");
		strcat(sdp_buff, SDP_EL);
		strcat(sdp_buff,"a=fmtp:96 packetization-mode=1;profile-level-id=1EE042;sprop-parameter-sets=QuAe2gLASRA=,zjCkgA==");
		strcat(sdp_buff, SDP_EL);
		strcat(sdp_buff,"a=control:");
		sprintf(sdp_buff + strlen(sdp_buff),"rtsp://%s/%s/trackID=0",rtsp_client_get_hostname(rtsp_client), rtsp_client_get_filename(rtsp_client));
		strcat(sdp_buff, SDP_EL);

	}
	strcat(sdp_buff, SDP_EL);

	return 0;
}


void add_time_stamp(char *b, int crlf)
{
     struct tm *t;
     time_t now;

     /*
      * concatenates a null terminated string with a
      * time stamp in the format of "Date: 23 Jan 1997 15:35:06 GMT"
      */
     now = time(NULL);
     t = gmtime(&now);
     strftime(b + strlen(b), 38, "Date: %a, %d %b %Y %H:%M:%S GMT"RTSP_EL, t);
     if (crlf)
    	 strcat(b, "\r\n");  /* add a message header terminator (CRLF) */
	return;
}


int send_describe_reply(int status, char* sdp_buffer, struct RtspClient* rtsp_client)
{
	char send_buffer[4096] = {0};

	/*describe*/
	sprintf(send_buffer, "%s %d %s"RTSP_EL"CSeq: %d"RTSP_EL"Server: %s/%s"RTSP_EL, RTSP_VER, status, _get_stat(status), rtsp_client_get_cseq(rtsp_client), PACKAGE, VERSION);	
	add_time_stamp(send_buffer, 0);
	strcat(send_buffer, "Content-Type: application/sdp"RTSP_EL);
	sprintf(send_buffer + strlen(send_buffer), "Content-Base: rtsp://%s/%s/"RTSP_EL,rtsp_client_get_hostname(rtsp_client), rtsp_client_get_filename(rtsp_client));
	sprintf(send_buffer + strlen(send_buffer), "Content-Length: %d"RTSP_EL, (int)strlen(sdp_buffer));
	strcat(send_buffer, RTSP_EL);
	/**** concatenate description ****/
	strcat(send_buffer, sdp_buffer);
	
	write(rtsp_client_get_fd(rtsp_client), send_buffer, strlen(send_buffer));

	return 0;
}


#define SDP_BUFFER_SIZE  4096

int rtsp_describe(struct RtspClient* rtsp_client)
{
	if(check_rtsp_url(rtsp_client)<0){	
		return -1;
	}

	if(check_rtsp_filename(rtsp_client)<0){
		return -1;
	}

	// Disallow Header REQUIRE
	if (strstr(rtsp_client_recv_request_string(rtsp_client), HDR_REQUIRE)) {
		send_reply(rtsp_client, 551);	/* Option not supported */
		return -1;
	}
	/* Get the description format. SDP is recomended */
	if (strstr(rtsp_client_recv_request_string(rtsp_client), HDR_ACCEPT) != NULL) {
		if (strstr(rtsp_client_recv_request_string(rtsp_client), "application/sdp") != NULL) {
			//descr_format = df_SDP_format;
			
		} else {
			// Add here new description formats
			send_reply(rtsp_client, 551);	/* Option not supported */
			return -1;
		}
	}
	if(_get_rtsp_cseg(rtsp_client)<0){
		return -1;
	}

	char* sdp_buffer = NULL;
	sdp_buffer  = malloc(SDP_BUFFER_SIZE);

	if(get_describe_sdp(sdp_buffer, rtsp_client)<0){
		return -1;
	}

    printf("###############################func(%s), line(%d): rtsp_client->sdp_buffer(%s) \n", __func__, __LINE__, sdp_buffer);

	if(send_describe_reply(200, sdp_buffer, rtsp_client)!=-1){
		return 1;
	}

	return 0;
}


unsigned long get_randdom_seq(void)
{
	unsigned long seed;
	srand((unsigned)time(NULL));  
	seed = 1 + (unsigned int) (rand()%(0xFFFF));	
	
	return seed;
}


int _gen_server_port(struct RtspClient* rtsp_client)
{
    int rtp_server_port = -1;
    int rtcp_server_port = -1;

    rtp_server_port = (rtsp_client_get_rtp_port(rtsp_client) - start_port)/2 + start_port;
    rtcp_server_port = rtp_server_port + 1;

    rtsp_client_set_rtp_ser_port(rtsp_client, rtp_server_port);
    rtsp_client_set_rtcp_ser_port(rtsp_client, rtcp_server_port);
    
	return 0;
}

int _gen_sessionid(struct RtspClient* rtsp_client)
{
    int session_id = -1;

    session_id =  1 + (int) (10.0 * rand() / (100000 + 1.0));
    rtsp_client_set_session_id(rtsp_client, session_id);
    
    return 0;
}

int send_setup_reply(int status, struct RtspClient* rtsp_client){
	char temp[30];
	char ttl[4];
    char send_buffer[1024]="";
	
	/* build a reply message */
	sprintf(send_buffer, "%s %d %s"RTSP_EL"CSeq: %d"RTSP_EL"Server: %s/%s"RTSP_EL, RTSP_VER, status, _get_stat(status), rtsp_client_get_cseq(rtsp_client), PACKAGE,
		VERSION);
	add_time_stamp(send_buffer, 0);
	strcat(send_buffer, "Session: ");
	_gen_sessionid(rtsp_client);
	sprintf(temp, "%d", rtsp_client_get_session_id(rtsp_client));
	strcat(send_buffer, temp);
	strcat(send_buffer, RTSP_EL);
	/**** unicast  ****/
	strcat(send_buffer, "Transport: RTP/AVP;unicast;client_port=");
	sprintf(temp, "%d", rtsp_client_get_rtp_port(rtsp_client));
	strcat(send_buffer, temp);
	strcat(send_buffer, "-");
	sprintf(temp, "%d", rtsp_client_get_rtcp_port(rtsp_client));
	strcat(send_buffer, temp);
	//sprintf(temp, ";source=%s", get_address());
	strcat(send_buffer,  rtsp_client_get_hostname(rtsp_client));
	strcat(send_buffer, temp);
	strcat(send_buffer, ";server_port=");
	sprintf(temp, "%d", rtsp_client_get_rtp_ser_port(rtsp_client));
	strcat(send_buffer, temp);
	strcat(send_buffer, "-");
	sprintf(temp, "%d", rtsp_client_get_rtcp_ser_port(rtsp_client));
	strcat(send_buffer, temp);
	sprintf(temp, ";ssrc=%u", rtsp_client_get_ssrc(rtsp_client));/*xxx*/
	strcat(send_buffer, temp);	
	strcat(send_buffer,";ttl=");
	sprintf(ttl,"%d",(int)DEFAULT_TTL);
	strcat(send_buffer,ttl);	
	strcat(send_buffer, RTSP_EL);
	strcat(send_buffer, RTSP_EL);

    printf("func(%s), line(%d): send setup udp string(%s) \n", __func__, __LINE__, send_buffer);
	
	write(rtsp_client_get_fd(rtsp_client), send_buffer, strlen(send_buffer));
	
	return 0;
}

int send_setup_tcp_reply(struct RtspClient* rtsp_client, int status)
{
	char temp[30] = {0};
    char out_buffer[1024] = {0};

	/* build a reply message */
	sprintf(out_buffer, "%s %d %s"RTSP_EL"CSeq: %d"RTSP_EL"Server: %s/%s"RTSP_EL, RTSP_VER, status, _get_stat(status),\
	    rtsp_client_get_cseq(rtsp_client), PACKAGE, VERSION);
	add_time_stamp(out_buffer, 0);
	strcat(out_buffer, "Session: ");
	_gen_sessionid(rtsp_client);
	sprintf(temp, "%d", rtsp_client_get_session_id(rtsp_client));
	strcat(out_buffer, temp);
	strcat(out_buffer, RTSP_EL);
	/**** unicast  ****/
	strcat(out_buffer, "Transport: RTP/AVP/TCP;interleaved=0-1;unicast;mode=play");

	strcat(out_buffer, RTSP_EL);
	strcat(out_buffer, RTSP_EL);
	
    printf("func(%s), line(%d): send tcp setup string(%s) \n", __func__, __LINE__, out_buffer);
    
	write(rtsp_client_get_fd(rtsp_client), out_buffer, strlen(out_buffer));
	
	return 0;
}

int rtsp_setup(struct RtspClient* rtsp_client)
{
	char *p = NULL;
	char trash[255], line[255];
	char *requset_string = NULL;
	int rtp_port;
	int rtcp_port;
	unsigned int seq;

	requset_string = rtsp_client_recv_request_string(rtsp_client);
	if(!requset_string){
		return -1;
	}


	if(_get_rtsp_cseg(rtsp_client)<0){
		return -1;
	}
	
	if ((p = strstr(requset_string, "client_port")) == NULL && 
		strstr(requset_string, "multicast") == NULL &&
		strstr(requset_string, "interleaved") == NULL) {
   		printf("func(%s), line(%d):   Not Acceptable\n", __func__, __LINE__);
		send_reply(rtsp_client, 406); /* Not Acceptable */	
		return -1;
	}
	/**** Start parsing the Transport header ****/
	if ((p = strstr(requset_string, HDR_TRANSPORT)) == NULL) {
   		printf("func(%s), line(%d):   Not Acceptable\n", __func__, __LINE__);
		send_reply(rtsp_client, 406);	/* Not Acceptable */
		return -1;
	}
	if (sscanf(p, "%10s%255s", trash, line) != 2) {
		printf("func(%s), line(%d):   Not Acceptable\n", __func__, __LINE__);
		send_reply(rtsp_client, 400);	/* Bad Request */
		return -1;
	}

	/****  get client rtp and rtcp port  ****/
	if(strstr(line, "client_port") != NULL){
		/*upd*/
		p = strstr(line, "client_port");
		p = strstr(p, "=");
		sscanf(p + 1, "%d", &(rtp_port));
		p = strstr(p, "-");
		sscanf(p + 1, "%d", &(rtcp_port));

		_gen_server_port(rtsp_client);
		seq = get_randdom_seq();
		rtsp_client_set_seq(rtsp_client, seq);
	//	rtsp_client->cmd_port.ssrc = random32(0);
        rtsp_client_set_ssrc(rtsp_client, seq);
        rtsp_client_set_timestamp(rtsp_client,htonl(1));
		rtsp_client_set_rtp_port(rtsp_client, rtp_port);
		rtsp_client_set_rtp_port(rtsp_client, rtcp_port);		

		rtsp_client_set_transport_mode(rtsp_client, RTSP_TRANSPORT_UDP);
		
		if(send_setup_reply(200,rtsp_client)!=-1){
			printf("Infor: send setup reply success!\n");
			return 1;
		}
	}
	
	if(strstr(line, "RTP/AVP/TCP") != NULL)  {
		/*line Transport: RTP/AVP/TCP;unicast;interleaved=0-1*/
		rtsp_client_set_transport_mode(rtsp_client, RTSP_TRANSPORT_TCP);
		if(send_setup_tcp_reply(rtsp_client, 200) != -1){
			printf("Infor: send tcp setup reply success!\n");
			return 1;
		}
	}
	
	return 0;
}


int send_play_reply(struct RtspClient* rtsp_client, int status)
{
	char temp[255] = {0};
	char out_buffer[1024] = {0};
    int ret = -1;

	/* build a reply message */
	sprintf(out_buffer, "%s %d %s"RTSP_EL"CSeq: %d"RTSP_EL"Server: %s/%s"RTSP_EL, RTSP_VER, status, _get_stat(status), rtsp_client_get_cseq(rtsp_client), PACKAGE, VERSION);
	add_time_stamp(out_buffer, 0);
	strcat(out_buffer, "Session: ");
	sprintf(temp, "%d", rtsp_client_get_session_id(rtsp_client));
	strcat(out_buffer, temp);
	strcat(out_buffer, RTSP_EL);
	strcat(out_buffer, RTSP_EL);
	ret = write(rtsp_client_get_fd(rtsp_client), out_buffer, strlen(out_buffer) + 1);

   
    if(ret == strlen(out_buffer) + 1){
        return 0;
    }
    
    return -1;
}

int rtsp_play(struct RtspClient* rtsp_client)
{
	char *p = NULL;
	char  trash[255] = {0};
	long session_id = 0;

#if 0
	/**** Parse the input message ****/
	if(check_rtsp_url(rtsp_client)<0){
		return -1;
	}
#endif

	if(_get_rtsp_cseg(rtsp_client)<0){
		return -1;
	}
	
	if(check_rtsp_filename(rtsp_client)<0){
		return -1;
	}
	
	if ((p = strstr(rtsp_client_recv_request_string(rtsp_client), HDR_SESSION)) != NULL) {
	    session_id = (long)rtsp_client_get_session_id(rtsp_client);
		if (sscanf(p, "%254s %ld", trash, &session_id) != 2) {
		    printf("func(%s) sessino not found\n", __func__);
			send_reply(rtsp_client, 454);	/* Session Not Found */
			return -1;
		}
	} else {
		send_reply(rtsp_client, 400);	/* bad request */
        printf("func(%s)  bad request\n", __func__);
		return -1;
	}
	
	if(send_play_reply(rtsp_client, 200) != 0){
        printf("func(%s)  send_play_reply failed\n", __func__);
		return -1;
	}
	
	return 0;
}

int send_terardown_reply(struct RtspClient* rtsp_client, int status)
{
	char temp[255];
	char out_buffer[1024] ={0};
	
	/* build a reply message */
	sprintf(out_buffer, "%s %d %s"RTSP_EL"CSeq: %d"RTSP_EL"Server: %s/%s"RTSP_EL, RTSP_VER, status, _get_stat(status), rtsp_client_get_cseq(rtsp_client), PACKAGE,
		VERSION);
	add_time_stamp(out_buffer, 0);
	strcat(out_buffer, "Session: ");
	sprintf(temp, "%d", rtsp_client_get_session_id(rtsp_client));
	strcat(out_buffer, temp);
	strcat(out_buffer, RTSP_EL);
	strcat(out_buffer, RTSP_EL);
	write(rtsp_client_get_fd(rtsp_client), out_buffer, strlen(out_buffer));

	return 0;
}

int rtsp_terardown(struct RtspClient* rtsp_client)
{
	char *p = NULL;
	char  trash[255] = {0};
	long session_id = 0;
	/**** Parse the input message ****/
#if 0
	if(check_rtsp_url(rtsp_client)<0){
		return -1;
	}
#endif

	if(_get_rtsp_cseg(rtsp_client) <0 ){
		return -1;
	}
	if(check_rtsp_filename(rtsp_client) <0 ){
		return -1;
	}

	if ((p = strstr(rtsp_client_recv_request_string(rtsp_client), HDR_SESSION)) != NULL) {
        session_id = (long)rtsp_client_get_session_id(rtsp_client);
		if (sscanf(p, "%254s %ld", trash, &session_id) != 2) {
			send_reply(rtsp_client, 454);	/* Session Not Found */
			return -1;
		}
	} 
	else {
		send_reply(rtsp_client, 400);	/* bad request */
		return -1;
	}
	if(send_terardown_reply(rtsp_client, 200)!=-1){
		return 1;
	}

	return 0;
}

int rtsp_send_reply(struct RtspClient* thiz, int errornumber)
{
    return send_reply(thiz, errornumber);
}

